/*
 * gpio.c
 *
 *  Created on: Feb 23, 2025
 *      Author: Young
 */
#include "gpio.h"

/*
 * defines
 *
 */
#define ADC_FILTER_SIZE			16
#define ADC_NUMBER				5
#define ADC_BUFFER_SIZE 		ADC_FILTER_SIZE * ADC_NUMBER

/*
 * externs
 *
 */
extern ADC_HandleTypeDef hadc1;

/*
 * globals
 *
 */
__IO uint16_t adcBuffer[ADC_BUFFER_SIZE];

/**
 * adcToInt
 *
 * @param
 * @return
 */
int16_t adcToInt(uint16_t adc, int16_t from, int16_t to) {
	int16_t _range = to - from;
	return adc * _range / 4095 + from;
}

/**
 * adcToFloat
 *
 * @param
 * @return
 */
float adcToFloat(uint16_t adc, float from, float to) {
	float _range = to - from;
	return adc * _range / 4095.0f + from;
}

/**
 * gpioSetup
 *
 * @param
 * @return
 */
void gpioSetup(void) {
// ADC
	HAL_ADCEx_Calibration_Start(&hadc1);
	HAL_ADC_Start_DMA(&hadc1, (uint32_t*) &adcBuffer, ADC_BUFFER_SIZE);
}

/**
 * gpioLoop
 *
 * @param
 * @return
 */
void gpioLoop(void) {
	// IO
	discreteInput[0] = I00;
	discreteInput[1] = I01;
	Q00(coil[0]);
	Q01(coil[1]);
	// AI
	inputRegister[0] = adcToInt(getAdcValue(0), 0, 1320);
	inputRegister[1] = adcToInt(getAdcValue(1), 0, 1320);
	// 电源电压VCC
	inputRegister[2] = adcToInt(getAdcValue(2), 0, 3630);
	// 芯片温度
	float _temp = (1.43f - adcToFloat(getAdcValue(3), 0, 3.3f)) / 0.0025f
			+ 25.0f;
	inputRegister[3] = (int16_t) (_temp * 10);
	// 芯片电压VDD
	inputRegister[4] = (1.2f * 4095) * 100 / getAdcValue(4);
}

/**
 * getAdcValue
 *
 * @param
 * @return
 */
uint16_t getAdcValue(int index) {
// 判断索引是否正确
	if (index < ADC_NUMBER) {
		// 和
		uint32_t sum = 0;
		for (int i = 0; i < ADC_FILTER_SIZE * ADC_NUMBER; i += ADC_NUMBER) {
			sum += adcBuffer[i + index];
		}
		//
		return sum / ADC_FILTER_SIZE;
	} else {
		return 0xFFFF;
	}
}
